package algorithms.concCBJ;

import java.util.Set;
import java.util.TreeSet;

import algorithms.TwoIntegers;


import general.CPA.CPA;
import general.conflictset.ArrayConflictSet;
import general.conflictset.ConflictSet;
import general.currentdomain.ArrayCurrentDomain;
import general.currentdomain.CurrentDomain;

/**
 * A class representing a SearchProcess
 * Contains information abotu a search process - its CPA, current domain, split set, was it marked as failed... and more
 */
public class CBJSearchProcess {

	private CurrentDomain domain;
	private CurrentDomain currentDomain;
	private int domainSize;
	private CPA cpa;
	private Set<TwoIntegers> splitSet;
	private CBJSearchProcess originSP;
	private boolean failed;
	private ConflictSet conflicts;

	/**
	 * Creates an instance of SearchProcess
	 * @param cpa CPA associated with this search process
	 * @param domainSize domain size of the agent
	 * @param dm the initial domain to use with this search process
	 */
	public CBJSearchProcess(CPA cpa, int domainSize, int n, CurrentDomain dm) {
		this.splitSet = new TreeSet<TwoIntegers>();
		this.cpa = cpa;
		this.domain = dm;
		this.domainSize = domainSize;
		this.failed = false;
		this.conflicts = new ArrayConflictSet(n);
		if (domainSize != -1)
			resetDomain();
	}

	/**
	 * returns the domain of the process
	 * @return
	 */
	public CurrentDomain getDomain() {
		return currentDomain;
	}

	public void resetDomain(){
		currentDomain = new ArrayCurrentDomain(domainSize);
		conflicts.reset();
		for (byte i=0; i<domainSize; i++){
			if (!domain.isInDomain(i)) currentDomain.remove(i);
		}
	}

	public CBJSearchProcess getOriginSP() {
		return originSP;
	}

	public void remove(TwoIntegers cpaId) {
		splitSet.remove(cpaId);
	}

	public boolean noMoreSplits() {
		return splitSet.isEmpty();
	}

	public void markFail() {
		failed = true;
	}
	
	public boolean isFailed() {
		return failed;
	}

	public CPA getCpa() {
		return cpa;
	}

	public void setOrigin(CBJSearchProcess sp) {
		this.originSP = sp;
		sp.splitSet.add(this.getId());
		//TODO THIS WAS THE FUCKING PROBLEM
	}

	public TwoIntegers getId() {
		if (cpa==null) return new TwoIntegers(-1,-1);
		return cpa.getId();
	}

//	public void addChildSp(SearchProcess newSP) {
//		splitSet.add(newSP.getId());
//	}
	public void addConflicts(ConflictSet conf){
		conflicts.addAll(conf);
	}

	public void updateCPA(CPA cpa) {
		this.cpa = cpa;
	}

	public void addConflict(byte other) {
		conflicts.insert(other);
	}

	public ConflictSet getConflicts() {
		return conflicts;
	}

}
